package com.benshou.bsoa.common.validate;

import com.benshou.bsoa.common.exception.BusinessException;
import jakarta.validation.Validator;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

/**
 * 自定义的参数校验器
 * 包装了原生的Validator，基于业务进行使用
 *
 * @author <a href="mailto:liuzhenbang@benshou.com">Liu Zhenbang</a>
 */
@RequiredArgsConstructor
public class IValidator {

    @NonNull
    private final Validator validator;

    /**
     * 对业务对象进行校验，如果校验不通过则抛出业务异常
     *
     * @param target 需要校验的对象，如果为null则跳过校验
     * @param groups 校验分组
     * @throws BusinessException 当校验不通过时抛出此异常，异常信息包含所有校验失败的属性及原因
     */
    public void validateOnBusiness(
            Object target,
            Class<?>... groups
    ) {
        // 空对象无法校验
        if (target == null) {
            return;
        }

        // 执行校验
        var validations = this.validator.validate(target, groups);
        if (validations == null || validations.isEmpty()) {
            return;
        }

        // 构建异常信息
        var builder = new StringBuilder("参数校验失败:");
        validations.forEach(
                validation -> builder
                        .append("\n- ")
                        .append(validation.getPropertyPath())
                        .append(": ")
                        .append(validation.getMessage())
        );
        throw new BusinessException(builder.toString());
    }
}
